<template>
  <div class="page-container">
    <div class="page-header">
      <h2>页面菜单管理</h2>
      <div class="header-actions">
        <el-button type="primary" @click="handleAdd">
          <Plus /> 添加菜单
        </el-button>
      </div>
    </div>

    <el-card>
      <el-table
        :data="menuTree"
        row-key="menu_id"
        :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
        border
        style="width: 100%"
        size="small"
      >
        <el-table-column prop="menu_code" label="菜单编码" width="150" />
        <el-table-column prop="menu_name" label="菜单名称" width="200" />
        <el-table-column prop="menu_path" label="菜单路径" width="200" />
        <el-table-column prop="component" label="组件路径" width="200" />
        <el-table-column prop="sort_order" label="排序" width="80" />
        <el-table-column label="状态" width="80">
          <template #default="{ row }">
            <el-tag :type="row.is_active ? 'success' : 'danger'">
              {{ row.is_active ? '启用' : '禁用' }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="200" align="center">
          <template #default="{ row }">
            <el-button size="small" @click="handleEdit(row)">编辑</el-button>
            <el-button size="small" type="danger" @click="handleDelete(row)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-card>

    <!-- 编辑/添加菜单对话框 -->
    <el-dialog v-model="dialogVisible" :title="dialogTitle" width="600px" draggable>
      <el-form :model="form" label-width="120px" ref="formRef">
        <el-form-item label="菜单编码" prop="menu_code" required>
          <el-input v-model="form.menu_code" placeholder="请输入菜单编码" />
        </el-form-item>

        <el-form-item label="菜单名称" prop="menu_name" required>
          <el-input v-model="form.menu_name" placeholder="请输入菜单名称" />
        </el-form-item>

        <el-form-item label="父菜单">
          <el-select v-model="form.parent_id" placeholder="选择父菜单" clearable>
            <el-option label="顶级菜单" :value="0" />
            <el-option
              v-for="item in menuOptions"
              :key="item.menu_id"
              :label="item.menu_name"
              :value="item.menu_id"
            />
          </el-select>
        </el-form-item>

        <el-form-item label="菜单路径" prop="menu_path">
          <el-input v-model="form.menu_path" placeholder="请输入菜单路径，如 /system/menu" />
        </el-form-item>

        <el-form-item label="组件路径" prop="component">
          <el-input v-model="form.component" placeholder="请输入组件路径，如 system/MenuManage" />
        </el-form-item>

        <el-form-item label="图标">
          <el-popover
            placement="bottom-start"
            :width="300"
            trigger="click"
            popper-class="icon-selector-popover"
          >
            <template #reference>
              <el-input
                v-model="form.icon"
                placeholder="请选择图标"
                readonly
                suffix-icon="ArrowDown"
              >
                <template #prepend>
                  <el-icon v-if="form.icon">
                    <component :is="form.icon" />
                  </el-icon>
                  <span v-else>无图标</span>
                </template>
              </el-input>
            </template>

            <div class="icon-selector">
              <div class="icon-search">
                <el-input
                  v-model="iconSearch"
                  placeholder="搜索图标..."
                  clearable
                  size="small"
                >
                  <template #prefix>
                    <el-icon><Search /></el-icon>
                  </template>
                </el-input>
              </div>

              <div class="icon-grid">
                <div
                  v-for="icon in filteredIcons"
                  :key="icon"
                  class="icon-item"
                  :class="{ active: form.icon === icon }"
                  @click="selectIcon(icon)"
                >
                  <el-icon :size="20">
                    <component :is="icon" />
                  </el-icon>
                  <span class="icon-name">{{ icon }}</span>
                </div>
              </div>

              <div v-if="filteredIcons.length === 0" class="no-icons">
                未找到相关图标
              </div>
            </div>
          </el-popover>
        </el-form-item>

        <el-form-item label="排序号">
          <el-input-number v-model="form.sort_order" :min="0" :step="1" />
        </el-form-item>

        <el-form-item label="是否启用">
          <el-switch v-model="form.is_active" />
        </el-form-item>

        <el-form-item label="描述">
          <el-input v-model="form.description" type="textarea" placeholder="请输入菜单描述" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" @click="handleSave">保存</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, computed, onMounted } from 'vue'
import { useSysMenuStore } from '@/stores/sys/SysMenuStore'
import { Plus, Search } from '@element-plus/icons-vue'
import type { SysMenu, SysMenuCreation, SysMenuUpdate } from '@/types/sys/SysMenu'
import { ElMessageBox, ElMessage } from 'element-plus'

// 常用图标列表
const commonIcons = [
  'HomeFilled',
  'Menu',
  'Document',
  'Setting',
  'Avatar',
  'Tickets',
  'User',
  'Lock',
  'Check',
  'Search',
  'Edit',
  'Delete',
  'Plus',
  'Minus',
  'CircleCheck',
  'CircleClose',
  'Warning',
  'InfoFilled',
  'Star',
  'Notification',
  'Message',
  'Calendar',
  'Picture',
  'Position',
  'Location',
  'Help',
  'Phone',
  'VideoPlay',
  'Upload',
  'Download'
]

// 获取菜单数据
const menuStore = useSysMenuStore()

// 计算属性获取菜单树
const menuTree = computed(() => {
  return menuStore.menuTree || []
})

// 对话框状态
const dialogVisible = ref(false)
const dialogTitle = ref('添加菜单')
const isEditing = ref(false)

// 图标搜索
const iconSearch = ref('')

// 表单引用
const formRef = ref()

// 表单数据
const form = reactive({
  menu_id: 0,
  menu_name: '',
  menu_code: '',
  parent_id: 0,
  menu_level: 1,
  menu_path: '',
  component: '',
  icon: '',
  sort_order: 0,
  is_active: true,
  description: ''
})

// 过滤后的图标列表
const filteredIcons = computed(() => {
  if (!iconSearch.value) {
    return commonIcons
  }
  return commonIcons.filter(icon =>
    icon.toLowerCase().includes(iconSearch.value.toLowerCase())
  )
})

// 用于下拉选择的菜单选项（排除当前编辑的菜单）
const menuOptions = computed(() => {
  // 只显示一级和二级菜单作为父级选项
  return menuStore.menuList.filter(item => {
    // 排除当前编辑的菜单及其子菜单，防止循环引用
    if (form.menu_id && isEditing.value) {
      return item.menu_id !== form.menu_id && !isChildOf(item.menu_id, form.menu_id)
    }
    return item.menu_level <= 2
  })
})

// 检查是否是子菜单
const isChildOf = (childId: number, parentId: number): boolean => {
  const child = menuStore.menuList.find(item => item.menu_id === childId)
  // 修复：处理 parent_id 可能为 undefined 的情况
  if (!child || !child.parent_id || child.parent_id === 0) {
    return false
  }
  if (child.parent_id === parentId) {
    return true
  }
  // 修复：确保传递给递归调用的参数不为 undefined
  return isChildOf(child.parent_id, parentId)
}

// 选择图标
const selectIcon = (icon: string) => {
  form.icon = icon
}

// 组件挂载时加载菜单数据
onMounted(async () => {
  await menuStore.fetchMenuList()
})

// 处理添加菜单
const handleAdd = () => {
  isEditing.value = false
  dialogTitle.value = '添加菜单'
  Object.assign(form, {
    menu_id: 0,
    menu_name: '',
    menu_code: '',
    parent_id: 0,
    menu_level: 1,
    menu_path: '',
    component: '',
    icon: '',
    sort_order: 0,
    is_active: true,
    description: ''
  })
  iconSearch.value = ''
  dialogVisible.value = true
}

// 打开编辑对话框
const handleEdit = (row: SysMenu) => {
  isEditing.value = true
  dialogTitle.value = '编辑菜单'
  Object.assign(form, row)
  iconSearch.value = ''
  dialogVisible.value = true
}

// 保存菜单
const handleSave = async () => {
  try {
    if (!isEditing.value) {
      // 添加菜单
      const newMenu: SysMenuCreation = {
        menu_name: form.menu_name,
        menu_code: form.menu_code,
        parent_id: form.parent_id,
        menu_level: form.parent_id === 0 ? 1 :
                   (menuStore.menuList.find(m => m.menu_id === form.parent_id)?.menu_level || 0) + 1,
        menu_path: form.menu_path,
        component: form.component,
        icon: form.icon,
        sort_order: form.sort_order,
        is_active: form.is_active,
        description: form.description
      }

      await menuStore.addMenu(newMenu)
      ElMessage.success('菜单添加成功')
    } else {
      // 更新菜单
      const menuId = form.menu_id

      if (!menuId || menuId <= 0) {
        ElMessage.error('无效的菜单ID')
        return
      }

      const updateData: SysMenuUpdate = {
        menu_name: form.menu_name,
        menu_code: form.menu_code,
        parent_id: form.parent_id,
        menu_path: form.menu_path,
        component: form.component,
        icon: form.icon,
        sort_order: form.sort_order,
        is_active: form.is_active,
        description: form.description
      }

      await menuStore.updateMenu(menuId, updateData)
      ElMessage.success('菜单更新成功')
    }

    dialogVisible.value = false
  } catch (error) {
    console.error('保存菜单失败:', error)
    ElMessage.error('保存菜单失败: ' + (error as Error).message)
  }
}

// 删除菜单
const handleDelete = async (row: SysMenu) => {
  try {
    await ElMessageBox.confirm(
      `确定要删除菜单"${row.menu_name}"吗？此操作不可恢复！`,
      '确认删除',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }
    )

    await menuStore.deleteMenu(row.menu_id)
    ElMessage.success('菜单删除成功')
  } catch (error) {
    if (!(error as Error).message?.includes('cancel')) {
      console.error('删除菜单失败:', error)
      ElMessage.error('删除菜单失败: ' + (error as Error).message)
    }
  }
}
</script>

<style scoped>
.page-container {
  padding: 20px;
}

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

:deep(.el-table__row td) {
  padding: 4px 0;
  font-size: 12px;
}

:deep(.el-table__header tr th) {
  padding: 6px 0;
  font-size: 12px;
}

.icon-selector-popover {
  padding: 0 !important;
}

.icon-selector {
  padding: 10px;
}

.icon-search {
  margin-bottom: 10px;
}

.icon-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 8px;
  max-height: 300px;
  overflow-y: auto;
}

.icon-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 8px 4px;
  border: 1px solid #ebeef5;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.2s;
}

.icon-item:hover {
  border-color: #409eff;
  background-color: #ecf5ff;
}

.icon-item.active {
  border-color: #409eff;
  background-color: #409eff;
  color: white;
}

.icon-item.active .icon-name {
  color: white;
}

.icon-name {
  font-size: 10px;
  margin-top: 4px;
  text-align: center;
  color: #909399;
  word-break: break-all;
}

.no-icons {
  text-align: center;
  color: #909399;
  padding: 20px 0;
}
</style>